import type { IAgentRuntime } from '../types/runtime';
import type { Memory } from '../types/memory';
import type { Content, UUID } from '../types/primitives';
import type { State } from '../types/state';
import type { HandlerCallback } from '../types/components';
import type { Room } from '../types/environment';
import type { MentionContext } from '../types/primitives';

/**
 * Configuration options for message processing
 */
export interface MessageProcessingOptions {
  /**
   * Maximum number of retries for LLM calls if required fields are missing
   * @default 3
   */
  maxRetries?: number;

  /**
   * Timeout for message processing in milliseconds
   * @default 3600000 (1 hour)
   */
  timeoutDuration?: number;

  /**
   * Whether to use multi-step workflow
   * @default false
   */
  useMultiStep?: boolean;

  /**
   * Maximum number of iterations for multi-step workflow
   * @default 6
   */
  maxMultiStepIterations?: number;
}

/**
 * Result of message processing
 */
export interface MessageProcessingResult {
  /**
   * Whether the agent decided to respond
   */
  didRespond: boolean;

  /**
   * The response content generated by the agent
   */
  responseContent: Content | null;

  /**
   * Response messages generated
   */
  responseMessages: Memory[];

  /**
   * Final state after processing
   */
  state: State;

  /**
   * Processing mode used ('simple', 'actions', or 'none')
   */
  mode?: 'simple' | 'actions' | 'none';
}

/**
 * Response decision from the shouldRespond logic
 */
export interface ResponseDecision {
  /**
   * Whether the agent should respond
   */
  shouldRespond: boolean;

  /**
   * Whether LLM evaluation can be skipped (decision made by rules)
   */
  skipEvaluation: boolean;

  /**
   * Reason for the decision (for debugging)
   */
  reason: string;
}

/**
 * Core interface for message handling service.
 * This service is responsible for processing incoming messages and generating responses.
 *
 * Implementations of this interface control the entire message processing pipeline,
 * including:
 * - Message validation and memory creation
 * - Response decision logic (shouldRespond)
 * - Single-shot or multi-step processing
 * - Action execution and evaluation
 *
 * @example
 * ```typescript
 * // Custom implementation
 * class CustomMessageService implements IMessageService {
 *   async handleMessage(runtime, message, callback) {
 *     // Your custom message handling logic
 *     return {
 *       didRespond: true,
 *       responseContent: { text: "Custom response" },
 *       responseMessages: [],
 *       state: {},
 *       mode: 'simple'
 *     };
 *   }
 *
 *   shouldRespond(runtime, message, room, mentionContext) {
 *     // Your custom response decision logic
 *     return { shouldRespond: true, skipEvaluation: true, reason: "custom" };
 *   }
 * }
 *
 * // Register in runtime
 * await runtime.registerService(CustomMessageService);
 * ```
 */
export interface IMessageService {
  /**
   * Main entry point for message processing.
   * This method orchestrates the entire message handling flow.
   *
   * @param runtime - The agent runtime instance
   * @param message - The incoming message to process
   * @param callback - Callback function to send responses
   * @param options - Optional processing options
   * @returns Promise resolving to the processing result
   */
  handleMessage(
    runtime: IAgentRuntime,
    message: Memory,
    callback?: HandlerCallback,
    options?: MessageProcessingOptions
  ): Promise<MessageProcessingResult>;

  /**
   * Determines whether the agent should respond to a message.
   * Uses simple rules for obvious cases (DM, mentions) and defers to LLM for ambiguous cases.
   *
   * @param runtime - The agent runtime instance
   * @param message - The message to evaluate
   * @param room - The room context (optional)
   * @param mentionContext - Platform mention/reply context (optional)
   * @returns Response decision with reasoning
   */
  shouldRespond(
    runtime: IAgentRuntime,
    message: Memory,
    room?: Room,
    mentionContext?: MentionContext
  ): ResponseDecision;

  /**
   * Processes attachments in a message (images, documents, etc.)
   * Generates descriptions for images and extracts text from documents.
   *
   * @param runtime - The agent runtime instance
   * @param attachments - Array of media attachments to process
   * @returns Promise resolving to processed attachments with descriptions
   */
  processAttachments?(runtime: IAgentRuntime, attachments: any[]): Promise<any[]>;

  /**
   * Deletes a message from the agent's memory.
   * This method handles the actual deletion logic that was previously in event handlers.
   *
   * @param runtime - The agent runtime instance
   * @param message - The message memory to delete
   * @returns Promise resolving when deletion is complete
   */
  deleteMessage(runtime: IAgentRuntime, message: Memory): Promise<void>;

  /**
   * Clears all messages from a channel/room.
   * This method handles bulk deletion of all message memories in a room.
   *
   * @param runtime - The agent runtime instance
   * @param roomId - The room ID to clear messages from
   * @param channelId - The original channel ID (for logging)
   * @returns Promise resolving when channel is cleared
   */
  clearChannel(runtime: IAgentRuntime, roomId: UUID, channelId: string): Promise<void>;
}
